﻿namespace FFF.Test.Startup
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Text.Encodings.Web;
    using System.Text.Unicode;
    using System.Threading.Tasks;
    using Abp;
    using Abp.Application.Services;
    using Abp.AspNetCore;
    using Abp.AspNetCore.Filters;
    using Abp.AspNetCore.Runtime.Cache;
    using Abp.AspNetCore.SignalR.Hubs;
    using Abp.Castle.Logging.Log4Net;
    using Abp.EntityFrameworkCore;
    using Castle.Facilities.Logging;
    using Hangfire;
    using log4net;
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.HttpsPolicy;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.Razor;
    using Microsoft.AspNetCore.StaticFiles;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.FileProviders;
    using Microsoft.Extensions.Options;
    using Microsoft.IdentityModel.Logging;
    using Microsoft.IdentityModel.Tokens;
    using Senparc.CO2NET;
    using Senparc.Weixin.Entities;
    using StackExchange.Profiling.Storage;
    using Swashbuckle.AspNetCore.Swagger;
    using Swashbuckle.AspNetCore.SwaggerGen;
    using UEditorNetCore;
    using FFF.Test.Application;
    using FFF.Test.Entity;
    using FFF.Test.Filters;
    using FFF.Test.Util.Consts;
    using FFF.Test.Util.Web;
    using Ydm.Extensions;

    /// <summary>
    /// 程序启动类
    /// </summary>
    public class Startup
    {
        /// <summary>
        /// 程序的配置类
        /// </summary>
        public IConfiguration Configuration { get; }

        private readonly IHostingEnvironment _env;

        /// <summary>
        /// Initializes a new instance of the <see cref="Startup"/> class.
        /// 注入配置对象
        /// </summary>
        /// <param name="configuration">配置的对象</param>
        /// <param name="hostingEnvironment">环境变量的配置</param>
        public Startup(IConfiguration configuration, IHostingEnvironment hostingEnvironment)
        {
            this.Configuration = configuration;
            this._env = hostingEnvironment;

            // 初始化全局配置
            AppConfigConsts.InitConfigBySettingJson((IConfigurationRoot)configuration);

            //var builder = new ConfigurationBuilder()
            //.SetBasePath(hostingEnvironment.ContentRootPath)
            //.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            //.AddJsonFile($"appsettings.{hostingEnvironment.EnvironmentName}.json", optional: true)
            //.AddEnvironmentVariables();
            //this.Configuration = builder.Build();
        }

        /// <summary>
        /// 配置依赖注入对象
        /// </summary>
        /// <param name="services">配置的services</param>
        /// <returns>配置的类</returns>
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            #region mvc配置
            MVCConfigurer.ConfigureServices(services, this.Configuration, this._env); // 配置查询views目录
            #endregion

            #region UEditor配置

            // 加入阿里云
            UEditorNetCore.Config.AliAccessKeyId = AppConfigConsts.AliAccessKeyId;
            UEditorNetCore.Config.AliAccessKeySecret = AppConfigConsts.AliAccessKeySecret;
            UEditorNetCore.Config.AliBucketName = AppConfigConsts.AliBucketName;
            UEditorNetCore.Config.AliEndpoint = AppConfigConsts.AliEndpoint;
            string json = Server.MapPath(@"~\lib\YdmJUI\static\plugins\ueditorAPP\config.json");
            services.AddUEditorService(json);
            #endregion

            #region 权限和文档配置
            AuthConfigurer.ConfigureServices(services, this.Configuration);
            DocConfigurer.ConfigureServices(services, this.Configuration, this._env);
            #endregion

            #region IM的配置
            IMConfigurer.ConfigureServices(services, this.Configuration, this._env);
            #endregion

            #region 微信的配置
            WxConfigurer.ConfigureServices(services, this.Configuration, this._env);
            #endregion

            #region MiniProfiler配置
            MiniProfilerConfigurer.ConfigureServices(services, this.Configuration, this._env);
            #endregion

            #region Hangfire 配置
            HangfireConfigurer.ConfigureServices(services, this.Configuration, this._env);
            #endregion

            #region abp配置   
            services.AddSingleton(HtmlEncoder.Create(UnicodeRanges.All)); // 防止cshtml编译中文进行编码

            return services.AddAbp<YdmAbpWebModule>(options =>
            {
                // Configure Log4Net logging
                options.IocManager.IocContainer.AddFacility<LoggingFacility>(
                    f => f.UseAbpLog4Net().WithConfig("log4net.config")
                );

            });
            #endregion
        }

        /// <summary>
        /// 用来初始化中间件的
        /// </summary>
        /// <param name="app">程序对象</param>
        /// <param name="env">程序运行的环境类</param>
        /// <param name="senparcSetting">基础配置</param>
        /// <param name="senparcWeixinSetting">微信配置</param>
        public void Configure(
            IApplicationBuilder app,
            IHostingEnvironment env,
            IOptions<SenparcSetting> senparcSetting,
            IOptions<SenparcWeixinSetting> senparcWeixinSetting)
        {
            MVCConfigurer.Configure(app, env);
            HangfireConfigurer.Configure(app, env);
            AbpConfigurer.Configure(app, env);

            MiddlewarConfigurer.Configure(app, env);

            SignalRConfigurer.Configure(app, env);
            MiniProfilerConfigurer.Configure(app, env);

            DocConfigurer.Configure(app, env);

            IMConfigurer.Configure(app, env);

            WxConfigurer.Configure(app, env, senparcSetting, senparcWeixinSetting);

            // mvc 路由规则
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
                routes.MapRoute(
                    name: "areas",
                    template: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
                  );
            });
        }

    }
}
